package com.hanZhe.shiro.realms;

import com.hanZhe.bean.User;
import com.hanZhe.service.UserService;


import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by shw on 2018-02-26.
 */
public class ShiroRealm extends AuthorizingRealm {

    //日志输出
    private static Logger log = LoggerFactory.getLogger(ShiroRealm.class);

    @Autowired
    private UserService userService;


    //认证的方法
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //1.把AuthenticationToken转换为UsernamePasswordToken
        UsernamePasswordToken upToken= (UsernamePasswordToken) token;

        //2.从usernamePasswordToken中获取username,即从前端获取的username
        String username = upToken.getUsername();
        log.info("前台获取到的密码----------------------"+upToken.getPassword());

        //3.调用数据库的方法，从数据库中查询username对应的用户记录
        User user = userService.selectUser(username);
        log.info("根据用户名在数据库中查询到的用户"+user);

        //4.若用户不存在，则可以抛出UnknowAccountException异常
        if(user==null){
            throw new UnknownAccountException("用户不存在");
        }else {
            //6.根据用户的情况，来构建AuthenticationInfo对象并返回,通常使用的实现类SimpleAuthenticationInfo
            //以下信息是从数据库中获取的

            //1.principal:认证的实体信息，可以是username，也可以是数据表对应的用户的实体类对象
            Object principal=user.getUsername();


            //2.credentials:密码
            Object credentials=user.getPassword();


            //3.realmName：当前的realm对象的name，调用父类的getName（）方法获取
            String realmName=getName();


            //4.盐值
            ByteSource credentialsSalt = ByteSource.Util.bytes(user.getUsername());
            log.info("credentialsSalt---------------"+credentialsSalt);
            SimpleAuthenticationInfo info=new SimpleAuthenticationInfo(principal,credentials,credentialsSalt,realmName);

            log.info("info-----------"+info);
            return info;
        }
//        //5.根据用户信息的情况，决定是否需要抛出其他的AuthenticationException异常
//        if("jwh".equals(username)){
//            throw new LockedAccountException("用户被锁定的异常");
//        }

    }

    //授权会被shiro回调的方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        log.info("----------------doGetAuthorizationInfo");
        //1.从principalCollection中获取登陆用户的信息
        Object principal=principalCollection.getPrimaryPrincipal();
        log.info("principal:"+principal);
        //2.利用登陆用户的信息来获取当前用户端的角色或权限（登陆用户信息中包含权限信息）（可能查询数据库）
        Set<String> reles=new HashSet<>();
        reles.add("user");
        if ("shw".equals(principal)){
            reles.add("admin");
        }
        //3.创建SimpleAuthorizationInfo，并设置其reles
        log.info("-------------------------------"+reles);
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(reles);
        //4.返回SimpleAuthorizationInfo对象

        return info;
    }
}
